package com.github.xaidanwang.auth.server.auth.phone;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert;

/**
 * @author wang yi fei
 * @date 2019/10/8 10:45
 */
public class PhoneAuthenticationProvider implements AuthenticationProvider {

	private UserDetailsService userDetailsService;
	private PasswordEncoder passwordEncode;

	public PhoneAuthenticationProvider(UserDetailsService userDetailsService) {
		Assert.notNull(userDetailsService);
		this.userDetailsService = userDetailsService;
		passwordEncode = new BCryptPasswordEncoder();
	}
	public PhoneAuthenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncode) {
		this.userDetailsService = userDetailsService;
		this.passwordEncode = passwordEncode;
	}

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		PhoneAuthenticationToken phoneAuthenticationToken = (PhoneAuthenticationToken)authentication;
		UserDetails userDetails = userDetailsService.loadUserByUsername((String) authentication.getPrincipal());
		if (passwordEncode.matches((String)phoneAuthenticationToken.getCredentials(),userDetails.getPassword())){
			throw new InternalAuthenticationServiceException("用户名或者密码不对");
		}
		PhoneAuthenticationToken authenticationResult = new PhoneAuthenticationToken(userDetails.getAuthorities(),userDetails.getUsername(),userDetails);
		return authenticationResult;
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return PhoneAuthenticationToken.class.isAssignableFrom(authentication);
	}

	public void setPasswordEncode(PasswordEncoder passwordEncode) {
		this.passwordEncode = passwordEncode;
	}

	public PasswordEncoder getPasswordEncode() {
		return passwordEncode;
	}
	public void setUserDetailsService(UserDetailsService userDetailsService) {
		this.userDetailsService = userDetailsService;
	}

	public UserDetailsService getUserDetailsService() {
		return userDetailsService;
	}
}
